import json
import sys
import matplotlib
matplotlib.use('QtAgg')  # 设置使用 Qt 兼容后端
from PyQt6 import QtWidgets
from PyQt6.QtCore import pyqtSignal
from PyQt6.QtGui import QPainter, QColor
from PyQt6.QtWidgets import QMessageBox, QVBoxLayout
from matplotlib.backends.backend_qtagg import (
    FigureCanvasQTAgg as FigureCanvas,
    NavigationToolbar2QT as NavigationToolbar,
)
import matplotlib.pyplot as plt
from matplotlib import rcParams
import 机械臂控制
from 简化界面设计 import Ui_MainWindow  # 导入你生成的UI类
import VTK成像  # 导入VTK成像函数
import 探头

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        # 服务器线程
        self.server_thread = None
        # show_message_box 信号连接到槽函数
        self.warning_signal.connect(self.show_message_box)
        # 创立探头类
        self.probe = 探头.Probe()
        # 探头的信号槽连接
        self.probe.probe_signal.connect(self.handle_probe_signal)
        # 创建折线图
        self.PictrueLayout = QVBoxLayout(self.Oscillogram)
        # Matplotlib 画布
        self.figure, self.ax = plt.subplots()
        self.canvas = FigureCanvas(self.figure)
        # 导航工具栏（用于放大、缩小等）
        self.toolbar = NavigationToolbar(self.canvas, self)
        # 将工具栏和画布添加到布局中
        self.PictrueLayout.addWidget(self.toolbar)
        self.PictrueLayout.addWidget(self.canvas)
        # 设置 Matplotlib 中文字体
        rcParams['font.sans-serif'] = ['SimHei']
        rcParams['axes.unicode_minus'] = False

        # 初始化 IncludeAngle 参数
        self.IncludeAngle.setProperty("value", 30)

        # 设置按钮功能连接
        self.SetPosition.setEnabled(False)  # 禁用 SetPosition 按钮
        self.RoboMove.setEnabled(False)  # 禁用 RoboMove 按钮
        self.CalculateMatrix.setEnabled(False)  # 禁用 CalculateMatrix 按钮
        self.CreatePointDB.setEnabled(False)  # 禁用 CreatePointDB 按钮
        self.SetPosition.clicked.connect(lambda: VTK成像.set_position(self.SetPosition, self))
        self.ReadFile.clicked.connect(lambda: VTK成像.openfile(self.FilePath))
        self.CreateDBFile.clicked.connect(lambda: VTK成像.vtk_make_db(self.FilePath, self.IncludeAngle.value()))
        self.CreateModule.clicked.connect(
            lambda: VTK成像.vtk_make_db_ui(self.FilePath.text(), self.VTKWidget, self, self.CreatePoint, self.ScanGap))
        self.CalculateMatrix.clicked.connect(lambda: 机械臂控制.rotationmatrix(self))
        self.CreatePointDB.clicked.connect(lambda: 机械臂控制.make_point_db(self))
        self.StartConnect.clicked.connect(self.start_server)
        self.StopConnect.clicked.connect(self.stop_server)
        self.RoboMove.clicked.connect(self.robo_move)
        self.device_status.clicked.connect(lambda: self.probe.set_parameter(self))
        self.pushButton.clicked.connect(lambda: self.probe.save_data(self))

        # 调整布局
        self.setup_layouts()
        self.setparam()

    def setup_layouts(self):
        # 设置 MainWindow 的布局
        main_layout = QtWidgets.QVBoxLayout(self.centralwidget)
        main_layout.setContentsMargins(0, 0, 0, 0)  # 去掉边缘间距
        main_layout.addWidget(self.tabWidget)

        # 调整 tab 页布局，使 VTKWidget 自动扩展
        tab_layout = QtWidgets.QVBoxLayout(self.tab)
        tab_layout.setContentsMargins(0, 0, 0, 0)  # 可以微调边距
        tab_layout.addWidget(self.VTKWidget, stretch=1)  # 设置 VTKWidget 可拉伸
        self.VTKWidget.setStyleSheet("border: 2px solid red;")  # 给 VTKWidget 加上边框

        spacer = QtWidgets.QSpacerItem(10, 50, QtWidgets.QSizePolicy.Policy.Minimum,
                                       QtWidgets.QSizePolicy.Policy.Expanding)
        tab_layout.addItem(spacer)

        # 将按钮等控件用水平布局固定在 VTKWidget 下方
        control_layout = QtWidgets.QHBoxLayout()
        control_layout.addWidget(self.ReadFile)
        control_layout.addWidget(self.CreateDBFile)
        control_layout.addWidget(self.CreateModule)
        control_layout.addWidget(self.CreatePoint)
        control_layout.addWidget(self.SetPosition)
        control_layout.addWidget(self.RoboMove)
        control_layout.setContentsMargins(0, 0, 0, 0)
        tab_layout.addLayout(control_layout)

        # 设置 ScanGap 和 IncludeAngle 控件固定位置
        extra_controls_layout = QtWidgets.QHBoxLayout()
        extra_controls_layout.addWidget(self.label)
        extra_controls_layout.addWidget(self.FilePath)
        extra_controls_layout.addWidget(self.label_11)
        extra_controls_layout.addWidget(self.ScanGap)
        extra_controls_layout.addWidget(self.label_10)
        extra_controls_layout.addWidget(self.IncludeAngle)
        extra_controls_layout.setContentsMargins(0, 0, 0, 0)  # 调整边距
        tab_layout.addLayout(extra_controls_layout)

        # 设置 VTKWidget 随窗口大小改变
        self.VTKWidget.setSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding)

        # 设置机械臂四点定位的提示信息,用if True:仅仅想让IDE能给我重叠
        if True:
            self.Rob1A1.setPlaceholderText("真实P1点的A1轴角度")
            self.Rob1A2.setPlaceholderText("真实P1点的A2轴角度")
            self.Rob1A3.setPlaceholderText("真实P1点的A3轴角度")
            self.Rob1A4.setPlaceholderText("真实P1点的A4轴角度")
            self.Rob1A5.setPlaceholderText("真实P1点的A5轴角度")
            self.Rob1A6.setPlaceholderText("真实P1点的A6轴角度")
            self.Rob2A1.setPlaceholderText("真实P2点的A1轴角度")
            self.Rob2A2.setPlaceholderText("真实P2点的A2轴角度")
            self.Rob2A3.setPlaceholderText("真实P2点的A3轴角度")
            self.Rob2A4.setPlaceholderText("真实P2点的A4轴角度")
            self.Rob2A5.setPlaceholderText("真实P2点的A5轴角度")
            self.Rob2A6.setPlaceholderText("真实P2点的A6轴角度")
            self.Rob3A1.setPlaceholderText("真实P3点的A1轴角度")
            self.Rob3A2.setPlaceholderText("真实P3点的A2轴角度")
            self.Rob3A3.setPlaceholderText("真实P3点的A3轴角度")
            self.Rob3A4.setPlaceholderText("真实P3点的A4轴角度")
            self.Rob3A5.setPlaceholderText("真实P3点的A5轴角度")
            self.Rob3A6.setPlaceholderText("真实P3点的A6轴角度")
            self.Rob4A1.setPlaceholderText("真实P4点的A1轴角度")
            self.Rob4A2.setPlaceholderText("真实P4点的A2轴角度")
            self.Rob4A3.setPlaceholderText("真实P4点的A3轴角度")
            self.Rob4A4.setPlaceholderText("真实P4点的A4轴角度")
            self.Rob4A5.setPlaceholderText("真实P4点的A5轴角度")
            self.Rob4A6.setPlaceholderText("真实P4点的A6轴角度")

    # 设置警告信息
    warning_signal = pyqtSignal(str)

    def show_message_box(self, message):
        QMessageBox.warning(self, "警告", message)

    # 服务器线程
    def start_server(self):
        if not self.server_thread:
            self.server_thread = 机械臂控制.ServerThread()
            self.RoboMove.setEnabled(False)
            self.server_thread.received_signal.connect(self.display_message)
            self.server_thread.close_signal.connect(self.stop_server)
            self.server_thread.RoboCtrl_signal.connect(self.RobCtrl_signal)
            self.server_thread.start()
            self.display_message("正在配置网络连接...")

    def robo_move(self):
        if not self.server_thread:
            self.server_thread = 机械臂控制.ServerThread(module=0)
            self.RoboMove.setEnabled(False)
            self.server_thread.received_signal.connect(self.display_message)
            self.server_thread.close_signal.connect(self.stop_server)
            self.server_thread.RoboCtrl_signal.connect(self.RobCtrl_signal)
            self.server_thread.now_pos_signal.connect(self.Rob_now_pos)
            self.server_thread.start()
            self.display_message("正在配置网络连接...")

    def display_message(self, message):
        """
        显示服务器收到的信息
        :param message: 服务器收到的信息
        """
        self.TCPInfo.appendPlainText(message)

    def RobCtrl_signal(self, confirm):
        self.RoboMove.setEnabled(confirm)

    def Rob_now_pos(self, now_pos):
        self.X.setText(str(now_pos[0]))
        self.Y.setText(str(now_pos[1]))
        self.Z.setText(str(now_pos[2]))
        self.A.setText(str(now_pos[3]))
        self.B.setText(str(now_pos[4]))
        self.C.setText(str(now_pos[5]))

    def stop_server(self):
        if self.server_thread:
            self.server_thread.stop()
            self.server_thread.wait()
            self.server_thread = None

    def closeEvent(self, event):
        if self.server_thread:
            self.server_thread.stop()
            self.server_thread.wait()
        super().closeEvent(event)

    # 设置超声参数设定集数据显示里控件的初始值和状态
    def setparam(self):
        # 设置采样率下拉框
        self.Sample_rate.addItem("100MSPS（默认）")
        self.Sample_rate.addItem("50MSPS")
        self.Sample_rate.addItem("25MSPS")
        self.Sample_rate.addItem("12.5MSPS")
        self.Sample_rate.addItem("6.25MSPS")
        self.Sample_rate.addItem("3.125MSPS")
        self.Sample_rate.addItem("1.5625MSPS")
        # 设置波形下拉框
        self.Wave_Form.addItem("全波整流")
        self.Wave_Form.addItem("正半波整流")
        self.Wave_Form.addItem("负半波整流")
        self.Wave_Form.addItem("原始波形（默认）")
        self.Wave_Form.setCurrentIndex(3)
        # 模式选择下拉框
        self.Model.addItem("同发同收（默认）")
        self.Model.addItem("不同发同收")
        # 发送通道下拉框
        self.TX_channel.addItems(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"])
        # 接收通道下拉框
        self.RX_channel.addItems(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"])
        # 硬件滤波下拉框
        self.hardfilter.addItems(["12kHz", "600kHz"])
        self.hardfilter.setCurrentIndex(1)
        # 采样点数
        self.buffer_length.setRange(1, 8192)
        self.buffer_length.setValue(3000)
        self.buffer_length.setSingleStep(1)
        self.buffer_length.setPrefix("缓冲区长度：")
        self.buffer_length.setWrapping(True)  # 循环滚动,即1减少后变为8192,8192增加后变为1，可有可无的功能
        # 数字低通滤波
        self.low_filter.setRange(0, 49999)
        self.low_filter.setValue(10000)
        self.low_filter.setSingleStep(1)
        self.low_filter.setPrefix("低通滤波：")
        self.low_filter.setWrapping(True)
        # 数字高通滤波
        self.high_filter.setRange(0, 49999)
        self.high_filter.setValue(2000)
        self.high_filter.setSingleStep(1)
        self.high_filter.setPrefix("高通滤波：")
        self.high_filter.setWrapping(True)
        # 接收延时
        self.receive_delay.setRange(0, 65530)
        self.receive_delay.setValue(2)
        self.receive_delay.setSingleStep(1)
        self.receive_delay.setPrefix("接收延时：")
        self.receive_delay.setWrapping(True)
        # 设置平均
        self.Aver.setRange(1, 200)
        self.Aver.setValue(10)
        self.Aver.setSingleStep(1)
        self.Aver.setPrefix("平均值：")
        self.Aver.setWrapping(True)
        # 脉冲电压映射
        self.slider_pluse_v.valueChanged.connect(self.slider_callback)
        # 脉冲宽度映射
        self.slider_pluse_w.valueChanged.connect(self.slider_callback)
        # 直流映射
        self.slider_DC.valueChanged.connect(self.slider_callback)
        # 增益映射
        self.slider_DB.valueChanged.connect(self.slider_callback)
        # 脉冲电压
        self.slider_pluse_v.setMaximum(255)
        self.slider_pluse_v.setMinimum(0)
        self.slider_pluse_v.setValue(0)
        # 脉冲宽度
        self.slider_pluse_w.setMaximum(25)
        self.slider_pluse_w.setMinimum(1)
        self.slider_pluse_w.setValue(1)
        # 直流偏置
        self.slider_DC.setMaximum(1023)
        self.slider_DC.setMinimum(0)
        self.slider_DC.setValue(511)
        # 增益设置
        self.slider_DB.setMaximum(1023)
        self.slider_DB.setMinimum(0)
        self.slider_DB.setValue(500)

    def slider_callback(self):
        # 真实脉冲电压显示
        self.label_v.setText(str(-(4 + 4000 / (0.392157 * (self.slider_pluse_v.value()) + 13.5))))
        # 真实脉冲宽度显示
        self.label_w.setText(str(20 * (self.slider_pluse_w.value()) + 30))
        # 接受增益显示
        self.label_gain.setText(str(0.0978 * (self.slider_DB.value() - 204)))
        # 直流偏置显示
        self.label_DC.setText(str(0.0048828 * (self.slider_DC.value() - 511)))

    def handle_probe_signal(self, probe_data):
        if probe_data == 0:
            print("探头异常")
        elif probe_data == 1:
            print("探头正常")
        elif probe_data == 2:
            # 开始绘图
            print("开始绘图")
            self.plot()

    def plot(self):
        if self.probe.received_data is None:
            print("未接收到数据")
            return
        else:
            # 清空以前的图像
            self.ax.clear()

            # 横坐标为列表元素序号，纵坐标为列表值
            x = list(range(len(self.probe.received_data)))
            y = self.probe.received_data

            # 绘制折线图
            self.ax.plot(x, y, marker=None, label="示例数据",color="black", linewidth=0.5)

            # 添加标题和标签
            self.ax.set_title("波形图")
            self.ax.set_xlabel("元素序号")
            self.ax.set_ylabel("值")
            self.ax.legend()

            # 刷新画布
            self.canvas.draw()


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)  # 创建一个应用程序
    window = MainWindow()  # 创建主窗口实例
    window.show()  # 显示主窗口
    sys.exit(app.exec())  # 运行应用程序的主循环
